package cbbx_sm.probabilistic_model;

import static org.junit.Assert.assertEquals;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;

import junit.framework.TestCase;

import org.junit.Test;

import cbbx_sm.parser.CameraData;
import cbbx_sm.parser.Parser;
import cbbx_sm.probabilistic_model.Cluster;
import cbbx_sm.probabilistic_model.ClusterAttributes;
import cbbx_sm.probabilistic_model.Clustering;
import cbbx_sm.probabilistic_model.NoisyOrPredictor;
import cbbx_sm.probabilistic_model.Prediction;
import cbbx_sm.probabilistic_model.ProbabilisticModel;
import cbbx_sm.probabilistic_model.SystemShortTermMemory;
import cbbx_sm.probabilistic_model.SystemState;
import cbbx_sm.utils.Utility;


/**
 * For debugging noisy-or algorithm in an ad-hoc way!
 * 
 * @author Alessio Della Motta - University of California, Irvine
 *
 */
public class NoisyOrAdHocTest_MultCam {
	
	@Test public void test() throws IOException{
		// This test is too long.
		assertEquals(1,2);
		CameraData data17 = Parser.parseFile("data/cameraData/2009052717.txt", "data/cameraData/2009052717.txt");
		data17.setImageFile("data/images/17.jpg");
		CameraData data18 = Parser.parseFile("data/cameraData/2009052718.txt", "data/cameraData/2009052718.txt");
		data18.setImageFile("data/images/18.jpg");
		
		List<CameraData> data = new Vector<CameraData>();
		data.add(data17);
		data.add(data18);
		
		List<Cluster> clusters17 = Utility.getClusters(Utility.clusters_17_15v2, "data/cameraData/2009052717.txt");
		List<Cluster> clusters18 = Utility.getClusters(Utility.clusters_18_15v1, "data/cameraData/2009052718.txt");
		Clustering._updateClustersForRadius(clusters17, Utility.getBoxes(data.get(0)));
		Clustering._updateClustersForRadius(clusters18, Utility.getBoxes(data.get(1)));
		
		List<Cluster> fusedClusters = new Vector<Cluster>();
		fusedClusters.addAll(clusters17);
		fusedClusters.addAll(clusters18);
		
	
		NoisyOrPredictor noisyOrPredictor;
		ProbabilisticModel probModel;
		SystemShortTermMemory memory = new SystemShortTermMemory(3);
		
		probModel = new ProbabilisticModel(data, fusedClusters);
		
		System.out.println(probModel);
		
		Prediction prediction = null;
//		noisyOrPredictor = new NoisyOrPredictor(probModel);
		noisyOrPredictor = new NoisyOrPredictor(memory, probModel, 3, fusedClusters, false);
		
		// Useful in order to build current system state
		HashMap<Cluster, ClusterAttributes> tempMap = new HashMap<Cluster, ClusterAttributes>();
		
		ClusterAttributes curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(false);
		tempMap.put(fusedClusters.get(0), curAttributes);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(true); //c1
		tempMap.put(fusedClusters.get(1), curAttributes);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(false);
		tempMap.put(fusedClusters.get(2), curAttributes);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(false);
		tempMap.put(fusedClusters.get(3), curAttributes);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(false);
		tempMap.put(fusedClusters.get(4), curAttributes);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(false);
		tempMap.put(fusedClusters.get(5), curAttributes);
		
		SystemState curState = new SystemState(0, tempMap);
		memory.updateMemory(curState);
//		noisyOrPredictor.makePrediction(curState);
		prediction = noisyOrPredictor.makePrediction();
		tempMap.clear();
		
		System.out.println("************* PREDICTION:\n" + prediction);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(false);
		tempMap.put(fusedClusters.get(0), curAttributes);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(false);
		tempMap.put(fusedClusters.get(1), curAttributes);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(false);
		tempMap.put(fusedClusters.get(2), curAttributes);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(true);//c3
		tempMap.put(fusedClusters.get(3), curAttributes);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(false);
		tempMap.put(fusedClusters.get(4), curAttributes);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(false);
		tempMap.put(fusedClusters.get(5), curAttributes);
		
		curState = new SystemState(1, tempMap);
		memory.updateMemory(curState);
		prediction = noisyOrPredictor.makePrediction();
		tempMap.clear();

		System.out.println("************* PREDICTION:\n" + prediction);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(false);
		tempMap.put(fusedClusters.get(0), curAttributes);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(false);
		tempMap.put(fusedClusters.get(1), curAttributes);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(false);
		tempMap.put(fusedClusters.get(2), curAttributes);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(false);
		tempMap.put(fusedClusters.get(3), curAttributes);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(true);//c4
		tempMap.put(fusedClusters.get(4), curAttributes);
		
		curAttributes = new ClusterAttributes();
		curAttributes.setContainsEntity(false);
		tempMap.put(fusedClusters.get(5), curAttributes);
		
		curState = new SystemState(2, tempMap);
		memory.updateMemory(curState);
		prediction = noisyOrPredictor.makePrediction();
		tempMap.clear();
		
		System.out.println("************* PREDICTION:\n" + prediction);
		
		int c1_index = probModel.getClusterIndex(fusedClusters.get(1));
		int c3_index = probModel.getClusterIndex(fusedClusters.get(3));
		int c4_index = probModel.getClusterIndex(fusedClusters.get(4));
		int c5_index = probModel.getClusterIndex(fusedClusters.get(5));
		
		double pc1_c3_3s = probModel.getIndependentTimeCorrelationProbability(2, c1_index, c3_index);
		double pc3_c3_2s = probModel.getIndependentTimeCorrelationProbability(1, c3_index, c3_index);
		double pc4_c3_1s = probModel.getIndependentTimeCorrelationProbability(0, c4_index, c3_index);
		double prob = 1 - (1 - pc1_c3_3s) * (1 - pc3_c3_2s) * (1 - pc4_c3_1s);
		TestCase.assertTrue(prediction.getClusterProbability(fusedClusters.get(3)) == prob);
		
		double pc1_c5_3s = probModel.getIndependentTimeCorrelationProbability(2, c1_index, c5_index);
		double pc3_c5_2s = probModel.getIndependentTimeCorrelationProbability(1, c3_index, c5_index);
		double pc4_c5_1s = probModel.getIndependentTimeCorrelationProbability(0, c4_index, c5_index);
		prob = 1 - (1 - pc1_c5_3s) * (1 - pc3_c5_2s) * (1 - pc4_c5_1s);
		TestCase.assertTrue(prediction.getClusterProbability(fusedClusters.get(5)) == prob);
	}
}
